﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Expect.Core.Interfaces;
using System.IO;

namespace Expect.Core.Test.IO
{
    using Expect.Core.BaseClasses;
    using Expect.Core.IO;

    class SampleSpecificationCheck
    {
        public static SpecificationDefinition ReadSpecification(ISpecificationReader reader, string ressourceFileName)
        {
            string specText = Helper.LoadFromRessourceFile(ressourceFileName);
            var res = reader.ReadSpecification(Path.GetFileNameWithoutExtension(ressourceFileName), specText);
            return res.Specification;
        }

        public static ParsingResult ExecuteFromText(object container, ISpecificationReader reader, string ressourceFileName)
        {
            string specText = Helper.LoadFromRessourceFile(ressourceFileName);
            var res = reader.ReadSpecification(ressourceFileName, specText);
            
            CheckSpecification(container, res.Specification);
            return res;
        }

        public static ParsingResult ExecuteFromStream(object container, ISpecificationReader reader, string ressourceFileName)
        {
            ParsingResult res = null;
            Helper.UseRessourceStream(
                ressourceFileName,
                input =>
                {
                    res = reader.ReadSpecification(ressourceFileName, input);
                }
            );

            CheckSpecification(container, res.Specification);
            return res;
        }

        public static void CheckSpecification(object container, SpecificationDefinition spec)
        {
            CheckSpecification(container, spec, true);
        }

        public static void CheckSpecification(object container, SpecificationDefinition spec, bool checkComments)
        {
            Assert.AreEqual(9, spec.Fixtures.Count, "Invalid fixture count");

            if (checkComments)
            {
                FixtureIsCommentHeader(spec, 0);
                FixtureIsCommentFooter(spec, 2);

                FixtureIsCommentHeader(spec, 3);
                FixtureIsCommentFooter(spec, 5);

                FixtureIsCommentHeader(spec, 6);
                FixtureIsCommentFooter(spec, 8);
            }

            DefaultSpecificationExecution runner = new DefaultSpecificationExecution();
            runner.Run(container, spec);
            if (!spec.IsSuccessful)
            {
                Assert.Fail(spec.GetMessageForFailedResult());
            }
            Assert.AreEqual(9, spec.Fixtures.Count, "Invalid number of fixtures");
        }

        public static void FixtureIsCommentHeader(SpecificationDefinition spec, int fixtureindex)
        {
            var fixture = spec.Fixtures[fixtureindex];
            Assert.AreEqual("this is a fixture text header", fixture.Rows[0].AsText());
            Assert.AreEqual("on multiple lines", fixture.Rows[1].AsText());
        }

        public static void FixtureIsCommentFooter(SpecificationDefinition spec, int fixtureindex)
        {
            var fixture = spec.Fixtures[fixtureindex];
            Assert.AreEqual("this is a fixture text footer", fixture.Rows[0].AsText());
        }
    }
}
